{
if(sis_apic_bug == -1)
sis_apic_bug = 0;
+ if (xen_start_info->flags & SIF_INITDOMAIN) {
+ dom0_op_t op = { .cmd = DOM0_PLATFORM_QUIRK };
+ op.u.platform_quirk.quirk_id = sis_apic_bug ?
+ QUIRK_IOAPIC_BAD_REGSEL : QUIRK_IOAPIC_GOOD_REGSEL;
+ HYPERVISOR_dom0_op(&op);
+ }
return 0;
}
case DOM0_PLATFORM_QUIRK:
{
extern int opt_noirqbalance;
- switch ( op->u.platform_quirk.quirk_id )
+ int quirk_id = op->u.platform_quirk.quirk_id;
+ switch ( quirk_id )
{
case QUIRK_NOIRQBALANCING:
printk("Platform quirk -- Disabling IRQ balancing/affinity.\n");
opt_noirqbalance = 1;
setup_ioapic_dest();
break;
+ case QUIRK_IOAPIC_BAD_REGSEL:
+ case QUIRK_IOAPIC_GOOD_REGSEL:
+#ifndef sis_apic_bug
+ sis_apic_bug = (quirk_id == QUIRK_IOAPIC_BAD_REGSEL);
+ printk("Platform info -- IO-APIC REGSEL is %s\n",
+ sis_apic_bug ? "bad" : "good");
+#else
+ BUG_ON(sis_apic_bug == (quirk_id == QUIRK_IOAPIC_BAD_REGSEL));
+#endif
+ break;
default:
ret = -EINVAL;
break;
int skip_ioapic_setup;
+#ifndef sis_apic_bug
+/*
+ * Is the SiS APIC rmw bug present?
+ * -1 = don't know, 0 = no, 1 = yes
+ */
+int sis_apic_bug = -1;
+#endif
+
/*
* # of IRQ routing registers
*/
*
* Older SiS APIC requires we rewrite the index regiser
*/
-#define sis_apic_bug 0 /* This may need propagating from domain0. */
+#ifdef __i386__
+extern int sis_apic_bug;
+#else
+#define sis_apic_bug 0
+#endif
static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
{
if (sis_apic_bug)
DEFINE_GUEST_HANDLE(dom0_getdomaininfolist_t);
#define DOM0_PLATFORM_QUIRK 39
-#define QUIRK_NOIRQBALANCING 1
+#define QUIRK_NOIRQBALANCING 1 /* Do not restrict IO-APIC RTE targets */
+#define QUIRK_IOAPIC_BAD_REGSEL 2 /* IO-APIC REGSEL forgets its value */
+#define QUIRK_IOAPIC_GOOD_REGSEL 3 /* IO-APIC REGSEL behaves properly */
typedef struct dom0_platform_quirk {
/* IN variables. */
uint32_t quirk_id;